const fs = require('fs')
const path = require('path')

function PC2CC(input) {
  return input.replace(/[A-Z]/g, letter => '-' + letter.toLowerCase()).substr(1)
}

// eslint-disable-next-line
function CC2PC(input) {
  return ('-' + input).replace(/\-[a-z]/g, atom => atom.substr(1).toUpperCase())
}

function PC2CN(input) {
  return PC2CC(input).split('-').map(it => it.toUpperCase()).join('_')
}

function PC2CF(input) {
  return PC2CN(input).toLowerCase()
}

function buildVue(name, className) {
  return `<template>
  <div class="${className}"></div>
</template>

<script>
export default {
  name: '${name}'
}
</script>

<style scoped>
.${className} {
  padding: 12px;
}
</style>
`
}

function App(args) {
  this.args = args
  // 创建Pack
  this.createpack = function(layer, name) {
    const dir = PC2CC(name)
    const dirPath = path.join(__dirname, './src', layer, dir)
    const indexFilePath = path.join(dirPath, 'index.js')
    const viewFilePath = path.join(dirPath, name + '.vue')
    const indexFileContent = `import ${name} from './${name}'

export default ${name}
`
    const viewFileContent = buildVue(name, dir)
    if (fs.existsSync(dirPath)) {
      console.log('文件夹已经存在，无法创建')
      return false
    }
    fs.mkdirSync(dirPath)
    fs.writeFileSync(indexFilePath, indexFileContent)
    fs.writeFileSync(viewFilePath, viewFileContent)
    console.log('成功')
    return true
  }
  // 创建vue
  this.createvue = function(name) {
    const dirPath = path.join(__dirname, './src')
    const vueFilePath = path.join(dirPath, name + '.vue')
    const vueFileContent = buildVue(name, PC2CC(name))
    if (fs.existsSync(vueFilePath)) {
      console.log('文件已经存在，无法创建')
      return false
    }
    fs.writeFileSync(vueFilePath, vueFileContent)
    console.log('成功')
    return true
  }
  // 创建view
  this.createview = function(name) {
    const dir = PC2CC(name)
    const ouputRoute = `
import ${name} from './views/${dir}'
{
  path: '/${dir}',
  name: '${dir}',
  component: ${name}
}
`
    if (this.createpack('views', name)) {
      console.log(ouputRoute)
    }
  }
  // 创建layout
  this.createlayout = function(name) {
    this.createpack('layouts', name)
  }
  // 创建component
  this.createcomp = function(name) {
    const compFilePath = path.join(__dirname, './src/components', name + '.vue')
    const ouputImport = `import ${name} from '@/components/${name}'`
    const compFileContent = buildVue(name, PC2CC(name))
    if (fs.existsSync(compFilePath)) {
      console.log('文件已经存在，无法创建')
      return
    }
    fs.writeFileSync(compFilePath, compFileContent)
    console.log('成功')
    console.log(ouputImport)
  }
  // 生成state
  this.makestate = function(name, ...options) {
    const has = key => options.indexOf(key) >= 0
    const isConfig = has('--config') || has('-c')
    let defaultValue = null
    if (isConfig) {
      options = options.filter(it => it !== '--config' && it !== '-c')
    }
    if (options.length > 0) {
      defaultValue = options.shift()
    }
    const stateName = name.charAt(0).toLowerCase() + name.substr(1)
    const mutationName = 'SET_' + PC2CN(name)
    const configName = PC2CF(name)
    const append = !isConfig ? '' : `
  config.write('${mutationName}', value)`
    const prefix = !isConfig ? '' : `{
  name: '${configName}',
  default: ${defaultValue},
  mutation: '${mutationName}'
}
`
    const output = `${prefix}${stateName}: ${defaultValue},
${stateName}: state => state.${stateName},
${mutationName}(state, value) {
  state.${stateName} = value${append}
}
    `
    console.log(output)
  }
  // 删除已存在的dll文件
  this.rmdll = function() {
    const dlls = fs.readdirSync(path.join(__dirname, './public/js'))
    for (const name of dlls) {
      if (/\.dll\.js$/.test(name)) {
        fs.unlinkSync(path.join(__dirname, './public/js', name))
      }
    }
  }
  // 修复dll依赖
  this.fixdll = function() {
    const dlls = fs.readdirSync(path.join(__dirname, './public/js'))
    const indexPath = path.join(__dirname, './public/index.html')
    const indexContent = fs.readFileSync(indexPath).toString()
    const injects = dlls.filter(name => /\.dll\.js$/.test(name)).map(name => `<script src="<%= BASE_URL %>js/${name}"></script>`)
    const inject = '\n    ' + injects.join('\n    ') + '\n    '
    const beginIndex = indexContent.indexOf('<!-- dll-begin -->')
    const endIndex = indexContent.indexOf('<!-- dll-end -->')
    const resultContent = indexContent.substr(0, beginIndex) + '<!-- dll-begin -->' + inject + indexContent.substr(endIndex)
    fs.writeFileSync(indexPath, resultContent)
  }
}

function main() {
  const args = process.argv.splice(2)
  const action = args.shift()
  const app = new App()
  if (app[action]) {
    app[action](...args)
  } else {
    console.log('Action not found: ' + action)
  }
}

main()
